package hw2;

import java.time.*;
import java.util.*;
import java.time.format.*;

public class Person {

    public static void main(String[] args) {
        Account A = new Account();
        A.menu();
    }

    static class Account {
        protected String date;
        protected String category;
        protected double amount;
        protected String note;
        protected double balance;
        private Scanner scanner = new Scanner(System.in);
        private List<Bill> bills; // 用于保存所有账单记录

        public Account() {
            this.balance = 0;
            this.bills = new ArrayList<>(); // 初始化账单列表
        }

        // 记录收入
        public void save(double income) {
            if (income > 0) {
                balance += income;
                bills.add(new Bill(date, income, category, note, true)); // 添加收入账单
            } else {
                System.out.println("收入金额必须大于0！");
            }
        }

        // 记录支出
        public void pay(double expense) {
            if (expense > 0 && expense <= balance) {
                balance -= expense;
                bills.add(new Bill(date, expense, category, note, false)); // 添加支出账单
                System.out.println("支出已成功记录！");
            } else if (expense <= 0) {
                System.out.println("支出金额必须大于0！");
            } else {
                System.out.println("余额不足，不能支出");
            }
        }

        // 菜单
        public void menu() {
            while (true) {
                System.out.println("=================================");
                System.out.println("欢迎使用个人账单管理系统");
                System.out.println("=================================");
                System.out.println("请选择操作：");
                System.out.println("1. 记录收入");
                System.out.println("2. 记录支出");
                System.out.println("3. 查看所有账单");
                System.out.println("4. 查询账单");
                System.out.println("5. 退出系统");
                System.out.print("请输入选项序号：");
                String choice = scanner.nextLine();

                switch (choice) {
                    case "1":
                        if (input("收入")) {
                            double income = getAmount();
                            if (income > 0) {
                                save(income);
                                System.out.println("收入已成功记录！");
                            }
                        } else {
                            System.out.println("输入错误");
                        }
                        break;

                    case "2":
                        if (input("支出")) {
                            double expense = getAmount();
                            if (expense > 0) {
                                pay(expense);
                            }
                        }
                        break;

                    case "3":
                        displayAllBills(); // 查看所有账单
                        break;

                    case "4":
                        checkBills(); // 查询账单
                        break;

                    case "5":
                        System.out.println("感谢使用个人账单管理系统，再见！");
                        scanner.close();
                        return;

                    default:
                        System.out.println("无效操作，请重试。");
                }
            }
        }

        // 输入日期、类别和备注
        private boolean input(String type) {
            for (int i = 0; i < 3; i++) {
                System.out.print("请输入" + type + "信息：\n日期（yyyy-MM-DD）：");
                date = scanner.nextLine();
                try {
                    LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    System.out.print("请输入" + type + "类别：");
                    category = scanner.nextLine();
                    if (category.isEmpty()) {
                        System.out.println(type + "类别不能为空，请重新输入！");
                        continue;
                    }
                    System.out.print("请输入" + type + "备注：");
                    note = scanner.nextLine();
                    if (note.isEmpty()) {
                        System.out.println(type + "备注不能为空，请重新输入！");
                        continue;
                    }
                    return true;
                } catch (DateTimeParseException e) {
                    System.out.println(type + "日期格式不正确，请重新输入！");
                }
            }
            System.out.println(type + "输入错误超过三次，返回主菜单。");
            return false;
        }

        private double getAmount() {
            for (int i = 0; i < 3; i++) {
                System.out.print("请输入金额：");
                if (scanner.hasNextDouble()) {
                    double amount = scanner.nextDouble();
                    scanner.nextLine();
                    if (amount > 0) {
                        return amount;
                    } else {
                        System.out.println("金额必须大于0，请重新输入！");
                    }
                } else {
                    System.out.println("无效的金额格式，请重新输入！");
                    scanner.nextLine();
                }
            }
            System.out.println("金额输入错误超过三次，返回主菜单。");
            return -1;
        }

        // 显示所有账单
        private void displayAllBills() {
            System.out.println("=================================");
            System.out.println("所有账单记录");
            System.out.println("=================================");
            System.out.println("收入账单:");
            for (Bill bill : bills) {
                if (bill.isIncome()) {
                    System.out.println(bill);
                }
            }
            System.out.println("支出账单:");
            for (Bill bill : bills) {
                if (!bill.isIncome()) {
                    System.out.println(bill);
                }
            }
        }

        // 查询账单
        private void checkBills() {
            System.out.println("请选择查询方式：");
            System.out.println("1. 按日期查询");
            System.out.println("2. 按日期范围查询");
            System.out.println("3. 按类别查询");
            String choice = scanner.nextLine();

            switch (choice) {
                case "1":
                    System.out.print("请输入查询日期（yyyy-MM-dd）：");
                    String dateInput = scanner.nextLine();
                    checkByDate(dateInput);
                    break;

                case "2":
                    System.out.print("请输入开始日期（yyyy-MM-dd）：");
                    String startDateInput = scanner.nextLine();
                    System.out.print("请输入结束日期（yyyy-MM-dd）：");
                    String endDateInput = scanner.nextLine();
                    checkByDateRange(startDateInput, endDateInput);
                    break;

                case "3":
                    System.out.print("请输入查询类别：");
                    String categoryInput = scanner.nextLine();
                    checkByCategory(categoryInput);
                    break;

                default:
                    System.out.println("无效操作，请重试。");
            }
        }

        // 按日期查询
        private void checkByDate(String dateInput) {
            LocalDate checkDate;
            System.out.println("=================================");
            System.out.println("查询结果（日期：" + dateInput + "）");
            System.out.println("=================================");
            boolean found = false;
            for (Bill bill : bills) {
                if (bill.getDate().equals(dateInput)) {
                    System.out.println(bill);
                    found = true;
                }
            }
            if (!found) {
                System.out.println("没有找到相关账单。");
            }
            try {
                checkDate = LocalDate.parse(dateInput, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                System.out.println("查询结果:");
                System.out.println("收入账单:");
                for (Bill bill : bills) {
                    if (bill.isIncome() && bill.getDate().equals(checkDate)) {
                        System.out.println(bill);
                    }
                }
                System.out.println("支出账单:");
                for (Bill bill : bills) {
                    if (!bill.isIncome() && bill.getDate().equals(checkDate)) {
                        System.out.println(bill);
                    }
                }
            } catch (DateTimeParseException e) {
                System.out.println("日期格式不正确。");
            }
        }

        // 按日期范围查询
        private void checkByDateRange(String startDateInput, String endDateInput) {
            System.out.println("=================================");
            System.out.println("查询结果（日期范围：" + startDateInput + " 到 " + endDateInput + "）");
            System.out.println("=================================");
            boolean found = false;

            LocalDate startDate = LocalDate.parse(startDateInput);
            LocalDate endDate = LocalDate.parse(endDateInput);

            for (Bill bill : bills) {
                LocalDate billDate = LocalDate.parse(bill.getDate());
                if ((billDate.isEqual(startDate) || billDate.isAfter(startDate)) &&
                        (billDate.isEqual(endDate) || billDate.isBefore(endDate))) {
                    System.out.println(bill);
                    found = true;
                }
            }
            if (!found) {
                System.out.println("没有找到相关账单。");
            }
            try {
                LocalDate startDate1 = LocalDate.parse(startDateInput, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                LocalDate endDate1 = LocalDate.parse(endDateInput, DateTimeFormatter.ofPattern("yyyy-MM-dd"));

                System.out.println("查询结果:");
                System.out.println("收入账单:");

                // 遍历账单并按收入和支出分类
                for (Bill bill : bills) {
                    LocalDate billDate = LocalDate.parse(bill.getDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    if ((billDate.isEqual(startDate) || billDate.isEqual(endDate) ||
                            (billDate.isAfter(startDate) && billDate.isBefore(endDate)))) {

                        if (bill.isIncome()) {
                            System.out.println(bill);
                        }
                    }
                }

                System.out.println("支出账单:");
                for (Bill bill : bills) {
                    LocalDate billDate = LocalDate.parse(bill.getDate(), DateTimeFormatter.ofPattern("yyyy-MM-dd"));
                    if ((billDate.isEqual(startDate) || billDate.isEqual(endDate) ||
                            (billDate.isAfter(startDate) && billDate.isBefore(endDate)))) {

                        if (!bill.isIncome()) {
                            System.out.println(bill);
                        }
                    }
                }
            } catch (DateTimeParseException e) {
                System.out.println("日期格式错误，请使用 yyyy-MM-dd 格式。");
            }
        }

        // 按类别查询账单
        private void checkByCategory(String categoryInput) {
            System.out.println("=================================");
            System.out.println("查询结果（类别：" + categoryInput + "）");
            System.out.println("=================================");
            boolean found = false;
            for (Bill bill : bills) {
                if (bill.getCategory().equalsIgnoreCase(categoryInput)) {
                    System.out.println(bill);
                    found = true;
                }
            }
            if (!found) {
                System.out.println("没有找到相关账单。");
            }
        }
    }

    // 账单类
    static class Bill {
        private String date;
        private double amount;
        private String note;
        private String category;
        private boolean isIncome;

        public Bill(String date, double amount, String note, String category, boolean isIncome) {
            this.date = date;
            this.amount = amount;
            this.note = note;
            this.category = category;
            this.isIncome = isIncome;
        }

        public String getDate() {
            return date;
        }

        public String getCategory() {
            return category;
        }

        public boolean isIncome() {
            return isIncome;
        }

        public String toString() {
            String type = isIncome ? "收入" : "支出";
            return type + ": " + String.format("%.2f", amount) + "元, 类别: " + category + ", 备注: " + note;
        }

    }
}
